﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Collections;

namespace SliderBarExt
{
    /// <summary>
    /// 多点滑块进度控件
    /// </summary>
    [ToolboxItem(true)]
    [DefaultProperty("Items")]
    [DefaultEvent("SlideValueChanged")]
    [Description("多点滑块进度控件")]
    public partial class SlideBarExt : Control
    {
        public delegate void EventHandler(object sender, SlideValueEventArgs e);

        #region 属性

        private event EventHandler slideValueChanged;
        /// <summary>
        /// 滑块选项值更改事件
        /// </summary>
        [Description("滑块选项值更改事件")]
        public event EventHandler SlideValueChanged
        {
            add { this.slideValueChanged += value; }
            remove { this.slideValueChanged -= value; }
        }

        private event EventHandler slideColorChanged;
        /// <summary>
        /// 滑块颜色改变事件
        /// </summary>
        [Description("滑块颜色改变事件")]
        public event EventHandler SlideColorChanged
        {
            add { this.slideColorChanged += value; }
            remove { this.slideColorChanged -= value; }
        }

        private SlideOrientation orientation = SlideOrientation.HorizontalBottom;
        /// <summary>
        /// 控件滑块方向位置
        /// </summary>
        [DefaultValue(SlideOrientation.HorizontalBottom)]
        [Description("控件滑块方向位置")]
        public SlideOrientation Orientation
        {
            get { return this.orientation; }
            set
            {
                if (this.orientation == value)
                    return;
                this.orientation = value;
                this.InitializeSlideValueRectangleFs();
                this.Invalidate();
            }
        }

        private int slidePadding = 6;
        /// <summary>
        /// 控件边距
        /// </summary>
        [DefaultValue(6)]
        [Description("控件边距")]
        public int SlidePadding
        {
            get { return this.slidePadding; }
            set
            {
                if (this.slidePadding == value || value < 0)
                    return;
                this.slidePadding = value;
                this.InitializeSlideValueRectangleFs();
                this.Invalidate();
            }
        }

        private float maxValue = 100f;
        /// <summary>
        /// 最大值
        /// </summary>
        [DefaultValue(100f)]
        [Description("最大值")]
        public float MaxValue
        {
            get { return this.maxValue; }
            set
            {
                if (this.maxValue == value || value < this.minValue)
                    return;
                this.maxValue = value;
                this.Invalidate();
            }
        }

        private float minValue = 0f;
        /// <summary>
        /// 最小值
        /// </summary>
        [DefaultValue(0f)]
        [Description("最小值")]
        public float MinValue
        {
            get { return this.minValue; }
            set
            {
                if (this.minValue == value || value > this.maxValue)
                    return;
                this.minValue = value;
                this.Invalidate();
            }
        }

        #region 背景

        private Color backdropColor = Color.FromArgb(76, 240, 128, 128);
        /// <summary>
        /// 背景颜色
        /// </summary>
        [DefaultValue(typeof(Color), "76, 240, 128, 128")]
        [Description("背景颜色")]
        [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
        public Color BackdropColor
        {
            get { return this.backdropColor; }
            set
            {
                if (this.backdropColor == value)
                    return;
                this.backdropColor = value;
                this.Invalidate();
            }
        }

        private int backdropThickness = 8;
        /// <summary>
        /// 背景大小
        /// </summary>
        [DefaultValue(8)]
        [Description("背景大小")]
        public int BackdropThickness
        {
            get { return this.backdropThickness; }
            set
            {
                if (this.backdropThickness == value || value < 0)
                    return;
                this.backdropThickness = value;
                this.Invalidate();
            }
        }

        private bool backdropRadius = true;
        /// <summary>
        /// 背景是否为圆角
        /// </summary>
        [Browsable(false)]
        [DefaultValue(true)]
        [Description("背景是否为圆角")]
        public bool BackdropRadius
        {
            get { return this.backdropRadius; }
            set
            {
                if (this.backdropRadius == value)
                    return;
                this.backdropRadius = value;
                this.Invalidate();
            }
        }

        #endregion

        #region 滑块

        private int slideSize = 8;
        /// <summary>
        /// 滑块大小
        /// 范围是垂直与刻度条的高Size*2,宽Size的矩形
        /// </summary>
        [DefaultValue(8)]
        [Description("滑块大小")]
        public int SlideSize
        {
            get { return this.slideSize; }
            set
            {
                if (this.slideSize == value || value < 0)
                    return;
                this.slideSize = value;
                this.InitializeSlideValueRectangleFs();
                this.Invalidate();
            }
        }

        private int cursorWidth = 1;
        /// <summary>
        /// 游标大小
        /// </summary>
        [DefaultValue(1)]
        [Description("游标大小")]
        public int CursorWidth
        {
            get { return this.cursorWidth; }
            set
            {
                if (this.cursorWidth == value || value < 0)
                    return;
                this.cursorWidth = value;
                this.InitializeSlideValueRectangleFs();
                this.Invalidate();
            }
        }

        private int slideWidth = 20;
        /// <summary>
        /// 滑块宽度
        /// </summary>
        [Browsable(false)]
        [DefaultValue(20)]
        [Description("滑块宽度")]
        public int SlideWidth
        {
            get { return this.slideWidth; }
            set
            {
                if (this.slideWidth == value || value < 0)
                    return;
                this.slideWidth = value;
                this.InitializeSlideValueRectangleFs();
                this.Invalidate();
            }
        }

        private int slideHeight = 20;
        /// <summary>
        /// 滑块高度
        /// </summary>
        [Browsable(false)]
        [DefaultValue(20)]
        [Description("滑块高度")]
        public int SlideHeight
        {
            get { return this.slideHeight; }
            set
            {
                if (this.slideHeight == value || value < 0)
                    return;
                this.slideHeight = value;
                this.InitializeSlideValueRectangleFs();
                this.Invalidate();
            }
        }

        private int slideRadius = 10;
        /// <summary>
        /// 滑块圆角大小(限于Flat)
        /// </summary>
        [Browsable(false)]
        [DefaultValue(10)]
        [Description("滑块圆角大小(限于Flat)")]
        public int SlideRadius
        {
            get { return this.slideRadius; }
            set
            {
                if (this.slideRadius == value || value < 0)
                    return;
                this.slideRadius = value;
                this.InitializeSlideValueRectangleFs();
                this.Invalidate();
            }
        }

        private Color slideColor = Color.FromArgb(255, 128, 128);
        /// <summary>
        /// 滑块颜色(总体设置)
        /// </summary>
        [DefaultValue(typeof(Color), "255, 128, 128")]
        [Description("滑块颜色(全局)")]
        [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
        public Color SlideColor
        {
            get { return this.slideColor; }
            set
            {
                if (this.slideColor == value)
                    return;
                this.slideColor = value;
                this.Invalidate();
            }
        }

        private Color slideProgressColor = Color.FromArgb(175, 240, 128, 128);
        /// <summary>
        /// 滑块进度颜色(仅限于只有一个滑块)
        /// </summary>
        [Browsable(false)]
        [DefaultValue(typeof(Color), "175, 240, 128, 128")]
        [Description("滑块进度颜色(仅限于只有一个滑块)")]
        [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
        public Color SlideProgressColor
        {
            get { return this.slideProgressColor; }
            set
            {
                if (this.slideProgressColor == value)
                    return;
                this.slideProgressColor = value;
                this.Invalidate();
            }
        }

        private int selectIndex = -1;
        /// <summary>
        /// 当前选中滑块的索引
        /// </summary>
        [Browsable(false)]
        [DefaultValue(-1)]
        [Description("当前选中滑块的索引")]
        public int SelectIndex
        {
            get { return this.selectIndex; }
        }

        private SlideValueCollection slideValueCollection;
        /// <summary>
        /// 滑块选项集合
        /// </summary>
        [DefaultValue(null)]
        [Description("滑块选项集合")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public SlideValueCollection Items
        {
            get
            {
                if (this.slideValueCollection == null)
                    this.slideValueCollection = new SlideValueCollection(this);
                return this.slideValueCollection;
            }
        }

        private bool enableColorChange = false;
        /// <summary>
        /// 指示用户是否可以通过双击滑块给滑块设置颜色
        /// </summary>
        [Browsable(true)]
        [DefaultValue(false)]
        [Description("是否可以通过双击改变滑块颜色")]
        public bool EnableColorChange
        {
            get { return this.enableColorChange; }
            set
            {
                if (this.enableColorChange == value)
                    return;
                this.enableColorChange = value;
            }
        }

        private bool lineshow = false;
        /// <summary>
        /// 是否绘制滑块与标签之间的连线
        /// </summary>
        [Browsable(false)]
        [DefaultValue(false)]
        [Description("绘制滑块与标签的连线")]
        public bool LineShow
        {
            get { return this.lineshow; }
            set
            {
                if (this.lineshow == value)
                    return;
                this.lineshow = value;
            }
        }

        private bool removeSlide = false;
        /// <summary>
        /// 用户是否可以通过滑出一定距离来移除滑块
        /// </summary>
        [Browsable(true)]
        [DefaultValue(false)]
        [Description("用户是否可以移除滑块")]
        public bool CanRemoveSlide
        {
            get { return this.removeSlide; }
            set
            {
                if (this.removeSlide == value)
                    return;
                else
                    this.removeSlide = value;
            }
        }

        private bool slideFixed = false;
        /// <summary>
        /// 用户是否可以移动滑块
        /// </summary>
        [DefaultValue(false)]
        [Description("滑块是否固定（全局）")]
        public bool SlideFixed
        {
            get { return this.slideFixed; }
            set
            {
                if (this.slideFixed == value)
                    return;
                else
                    this.slideFixed = value;
            }
        }

        #endregion

        #region 提示信息

        private TipShowEnum tipShow = TipShowEnum.Always;
        /// <summary>
        /// 是否显示提示信息
        /// </summary>
        [DefaultValue(TipShowEnum.Always)]
        [Description("是否显示提示信息")]
        public TipShowEnum TipShow
        {
            get { return this.tipShow; }
            set
            {
                if (this.tipShow == value)
                    return;
                this.tipShow = value;
                this.Invalidate();
            }
        }

        private Color tipBackdropColor = Color.FromArgb(126, 255, 128, 128);
        /// <summary>
        /// 提示信息背景颜色
        /// </summary>
        [DefaultValue(typeof(Color), "126, 255, 128, 128")]
        [Description("提示信息背景颜色")]
        [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
        public Color TipBackdropColor
        {
            get { return this.tipBackdropColor; }
            set
            {
                if (this.tipBackdropColor == value)
                    return;
                this.tipBackdropColor = value;
                this.Invalidate();
            }
        }

        private Font tipFont = new Font("宋体", 11, FontStyle.Regular);
        /// <summary>
        /// 提示信息字体
        /// </summary>
        [DefaultValue(typeof(Font), "11pt style=Regular")]
        [Description("提示信息字体")]
        public Font TipFont
        {
            get { return this.tipFont; }
            set
            {
                if (this.tipFont == value)
                    return;
                this.tipFont = value;
                this.Invalidate();
            }
        }

        private Color tipColor = Color.FromArgb(150, 255, 255, 255);
        /// <summary>
        /// 提示信息颜色
        /// </summary>
        [DefaultValue(typeof(Color), "150,255, 255, 255")]
        [Description("提示信息颜色")]
        [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
        public Color TipColor
        {
            get { return this.tipColor; }
            set
            {
                if (this.tipColor == value)
                    return;
                this.tipColor = value;
                this.Invalidate();
            }
        }

        #endregion

        protected override Size DefaultSize
        {
            get
            {
                return new Size(300, 60);
            }
        }

        /// <summary>
        /// 鼠标状态
        /// </summary>
        private MoveStatus move_status = MoveStatus.Leave;
        /// <summary>
        /// 鼠标坐标
        /// </summary>
        private Point move_point;

        #endregion

        public SlideBarExt()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);

            InitializeComponent();
        }

        #region 重写方法
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;
            Rectangle rectf = new Rectangle(this.SlidePadding, this.SlidePadding, e.ClipRectangle.Width - this.SlidePadding * 2, e.ClipRectangle.Height - this.SlidePadding * 2);

            #region 背景

            if (this.Items.Count > 0)
            {
                int backdrop_x_start = 0;
                int backdrop_x_end = 0;
                int backdrop_y = 0;
                float value2pixel = 0;
                LinearGradientBrush backdrop_brush;
                Pen backdrop_linerGradientPen;
                if (this.Orientation == SlideOrientation.HorizontalTop || this.Orientation == SlideOrientation.HorizontalBottom)
                {
                    backdrop_y = (this.Orientation == SlideOrientation.HorizontalTop) ? rectf.Y + this.SlideSize * 2 + this.BackdropThickness / 2 :
                        rectf.Bottom - this.SlideSize * 2 - this.BackdropThickness / 2;
                    value2pixel = (rectf.Width - this.SlideSize) / (this.maxValue - this.minValue);
                    backdrop_x_end = rectf.X + (int)((this.Items[0].Value - this.minValue) * value2pixel) + this.SlideSize / 2;
                    backdrop_x_start = rectf.X + this.SlideSize / 2;
                    if (backdrop_x_start != backdrop_x_end)
                    {
                        backdrop_brush = new LinearGradientBrush(new Point(backdrop_x_start, backdrop_y),
                            new Point(backdrop_x_end, backdrop_y), this.Items[0].SlideColor, this.Items[0].SlideColor);
                        backdrop_linerGradientPen = new Pen(backdrop_brush, this.BackdropThickness);
                        g.DrawLine(backdrop_linerGradientPen, backdrop_x_start, backdrop_y, backdrop_x_end, backdrop_y);
                        backdrop_brush.Dispose();
                        backdrop_linerGradientPen.Dispose();
                    }
                    if (this.Items.Count > 1)
                    {
                        for (int i = 1; i < this.Items.Count; ++i)
                        {
                            backdrop_x_start = backdrop_x_end + this.CursorWidth;
                            backdrop_x_end = backdrop_x_start + (int)((this.Items[i].Value - this.Items[i - 1].Value) * value2pixel) + this.CursorWidth;
                            if (backdrop_x_start != backdrop_x_end)
                            {
                                backdrop_brush = new LinearGradientBrush(new Point(backdrop_x_start, backdrop_y), new Point(backdrop_x_end, backdrop_y),
                                    this.Items[i - 1].SlideColor, this.Items[i].SlideColor);
                                backdrop_linerGradientPen = new Pen(backdrop_brush, this.BackdropThickness);
                                g.DrawLine(backdrop_linerGradientPen, backdrop_x_start, backdrop_y, backdrop_x_end, backdrop_y);
                                backdrop_brush.Dispose();
                                backdrop_linerGradientPen.Dispose();
                            }
                        }
                    }
                    backdrop_x_start = backdrop_x_end + this.CursorWidth;
                    backdrop_x_end = rectf.Right - this.SlideSize / 2;
                    if (backdrop_x_start != backdrop_x_end)
                    {
                        backdrop_brush = new LinearGradientBrush(new Point(backdrop_x_start, backdrop_y), new Point(backdrop_x_end, backdrop_y),
                            this.Items[this.Items.Count - 1].SlideColor, this.Items[this.Items.Count - 1].SlideColor);
                        backdrop_linerGradientPen = new Pen(backdrop_brush, this.BackdropThickness);
                        g.DrawLine(backdrop_linerGradientPen, backdrop_x_start, backdrop_y, backdrop_x_end, backdrop_y);
                        backdrop_brush.Dispose();
                        backdrop_linerGradientPen.Dispose();
                    }
                }
                else
                {
                    backdrop_y = (this.Orientation == SlideOrientation.VerticalLeft) ? this.SlideSize * 2 + this.BackdropThickness / 2 :
                        rectf.Right - this.SlideSize * 2 - this.BackdropThickness / 2;
                    value2pixel = (rectf.Height - this.SlideSize) / (this.maxValue - this.minValue);
                    backdrop_x_start = rectf.Bottom - (int)((this.Items[0].Value - this.minValue) * value2pixel) - this.SlideSize / 2;
                    backdrop_x_end = rectf.Bottom - this.SlideSize / 2;
                    if (backdrop_x_start != backdrop_x_end)
                    {
                        backdrop_brush = new LinearGradientBrush(new Point(backdrop_y, backdrop_x_start),
                            new Point(backdrop_y, backdrop_x_end), this.Items[0].SlideColor, this.Items[0].SlideColor);
                        backdrop_linerGradientPen = new Pen(backdrop_brush, this.BackdropThickness);
                        g.DrawLine(backdrop_linerGradientPen, backdrop_y, backdrop_x_start, backdrop_y, backdrop_x_end);
                        backdrop_brush.Dispose();
                        backdrop_linerGradientPen.Dispose();
                    }
                    if (this.Items.Count > 1)
                    {
                        for (int i = 1; i < this.Items.Count; ++i)
                        {
                            backdrop_x_end = backdrop_x_start - this.CursorWidth;
                            backdrop_x_start = backdrop_x_end - (int)((this.Items[i].Value - this.Items[i - 1].Value) * value2pixel) - this.CursorWidth;
                            if (backdrop_x_start != backdrop_x_end)
                            {
                                backdrop_brush = new LinearGradientBrush(new Point(backdrop_y, backdrop_x_start), new Point(backdrop_y, backdrop_x_end),
                                    this.Items[i].SlideColor, this.Items[i - 1].SlideColor);
                                backdrop_linerGradientPen = new Pen(backdrop_brush, this.BackdropThickness);
                                g.DrawLine(backdrop_linerGradientPen, backdrop_y, backdrop_x_start, backdrop_y, backdrop_x_end);
                                backdrop_brush.Dispose();
                                backdrop_linerGradientPen.Dispose();
                            }
                        }
                    }
                    backdrop_x_end = backdrop_x_start - this.CursorWidth;
                    backdrop_x_start = rectf.Y + this.SlideSize / 2;
                    if (backdrop_x_start != backdrop_x_end)
                    {
                        backdrop_brush = new LinearGradientBrush(new Point(backdrop_y, backdrop_x_start), new Point(backdrop_y, backdrop_x_end),
                            this.Items[this.Items.Count - 1].SlideColor, this.Items[this.Items.Count - 1].SlideColor);
                        backdrop_linerGradientPen = new Pen(backdrop_brush, this.BackdropThickness);
                        g.DrawLine(backdrop_linerGradientPen, backdrop_y, backdrop_x_start, backdrop_y, backdrop_x_end);
                        backdrop_brush.Dispose();
                        backdrop_linerGradientPen.Dispose();
                    }
                }
            }
            else
            {
                Pen backdrop = new Pen(this.backdropColor, this.BackdropThickness);
                switch (this.Orientation)
                {
                    case SlideOrientation.HorizontalTop:
                        g.DrawLine(backdrop, new Point(rectf.X + this.SlideSize / 2, rectf.Y + this.SlideSize * 2), new Point(rectf.Right - this.SlideSize / 2, rectf.Y + this.SlideSize * 2));
                        break;
                    case SlideOrientation.HorizontalBottom:
                        g.DrawLine(backdrop, new Point(rectf.X + this.SlideSize / 2, rectf.Bottom - this.SlideSize * 2), new Point(rectf.Right - this.SlideSize / 2, rectf.Bottom - this.SlideSize * 2));
                        break;
                    case SlideOrientation.VerticalLeft:
                        g.DrawLine(backdrop, new Point(rectf.X + this.SlideSize * 2, rectf.Y + this.SlideSize / 2), new Point(rectf.X + this.SlideSize * 2, rectf.Bottom - this.SlideSize / 2));
                        break;
                    case SlideOrientation.VerticalRight:
                        g.DrawLine(backdrop, new Point(rectf.Right - this.SlideSize * 2, rectf.Y + this.SlideSize / 2), new Point(rectf.Right - this.SlideSize * 2, rectf.Bottom - this.SlideSize / 2));
                        break;
                }
            }
            #endregion

            #region  滑块

            int line_area = 6;//连线区域大小
            Pen tooltipline_pen = new Pen(this.TipBackdropColor, 2);
            SolidBrush tooltipback_sb = new SolidBrush(this.TipBackdropColor);
            for (int i = 0; i < this.Items.Count; i++)
            {
                #region 滑块
                if(this.Items[i].Visuable)
                {
                    SolidBrush slide_sb = new SolidBrush(this.Items[i].SlideColor == Color.Empty ? this.SlideColor : this.Items[i].SlideColor);
                    GraphicsPath slide_gp = new GraphicsPath();
                    switch (this.Orientation)
                    {
                        case SlideOrientation.HorizontalTop:
                            slide_gp.AddPolygon(new PointF[]{ new PointF(this.Items[i].RectF.X,this.Items[i].RectF.Y),
                                            new PointF(this.Items[i].RectF.Right,this.Items[i].RectF.Y),
                                            new PointF(this.Items[i].RectF.Right,this.Items[i].RectF.Y + this.SlideSize),
                                            new PointF(this.Items[i].RectF.X + this.SlideSize / 2,this.Items[i].RectF.Bottom),
                                            new PointF(this.Items[i].RectF.X,this.Items[i].RectF.Y + this.SlideSize) });
                            break;
                        case SlideOrientation.HorizontalBottom:
                            slide_gp.AddPolygon(new PointF[]{ new PointF(this.Items[i].RectF.X,this.Items[i].RectF.Bottom),
                                            new PointF(this.Items[i].RectF.X,this.Items[i].RectF.Y + this.SlideSize),
                                            new PointF(this.Items[i].RectF.X + this.SlideSize / 2,this.Items[i].RectF.Y),
                                            new PointF(this.Items[i].RectF.Right,this.Items[i].RectF.Y + this.SlideSize),
                                            new PointF(this.Items[i].RectF.Right,this.Items[i].RectF.Bottom) });
                            break;
                        case SlideOrientation.VerticalLeft:
                            slide_gp.AddPolygon(new PointF[]{ new PointF(this.Items[i].RectF.X,this.Items[i].RectF.Y),
                                            new PointF(this.Items[i].RectF.X + this.SlideSize,this.Items[i].RectF.Y),
                                            new PointF(this.Items[i].RectF.Right,this.Items[i].RectF.Y + this.SlideSize / 2),
                                            new PointF(this.Items[i].RectF.X + this.SlideSize,this.Items[i].RectF.Bottom),
                                            new PointF(this.Items[i].RectF.X,this.Items[i].RectF.Bottom) });
                            break;
                        case SlideOrientation.VerticalRight:
                            slide_gp.AddPolygon(new PointF[]{ new PointF(this.Items[i].RectF.Right,this.Items[i].RectF.Bottom),
                                            new PointF(this.Items[i].RectF.X+ this.SlideSize,this.Items[i].RectF.Bottom),
                                            new PointF(this.Items[i].RectF.X,this.Items[i].RectF.Y + this.SlideSize / 2),
                                            new PointF(this.Items[i].RectF.X+ this.SlideSize,this.Items[i].RectF.Y ),
                                            new PointF(this.Items[i].RectF.Right,this.Items[i].RectF.Y) });
                            break;
                    }
                    Pen slide_bd = new Pen(Color.Black, 1);
                    g.DrawPath(slide_bd, slide_gp);
                    g.FillPath(slide_sb, slide_gp);
                    slide_bd.Dispose();
                    slide_gp.Dispose();
                    slide_sb.Dispose();
                }
                #endregion

                #region 计算提示信息的位置
                if (this.TipShow != TipShowEnum.None)
                {
                    string tooltiptext_str = this.Items[i].Value.ToString("F2");
                    Size tooltiptext_size = TextRenderer.MeasureText(tooltiptext_str, this.TipFont, new Size(), TextFormatFlags.NoPadding | TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);

                    Rectangle tooltipback_rect = new Rectangle(0, 0, tooltiptext_size.Width, tooltiptext_size.Height);
                    if (this.Orientation == SlideOrientation.HorizontalTop)
                    {
                        tooltipback_rect.X = (int)this.Items[i].RectF.X + ((int)this.Items[i].RectF.Width - tooltipback_rect.Width) / 2;
                        if (tooltipback_rect.X < 0)
                            tooltipback_rect.X = 0;
                        tooltipback_rect.Y = (int)this.Items[i].RectF.Bottom + this.BackdropThickness;
                        if (i > 0 && (tooltipback_rect.X < this.Items[i - 1].TipRect.Right + line_area))
                        {
                            tooltipback_rect.X = (int)this.Items[i - 1].TipRect.Right + line_area;
                        }
                    }
                    else if (this.Orientation == SlideOrientation.HorizontalBottom)
                    {
                        tooltipback_rect.X = (int)this.Items[i].RectF.X + ((int)this.Items[i].RectF.Width - tooltipback_rect.Width) / 2;
                        if (tooltipback_rect.X < 0)
                            tooltipback_rect.X = 0;
                        tooltipback_rect.Y = (int)this.Items[i].RectF.Y - this.BackdropThickness - tooltipback_rect.Height;
                        if (i > 0 && (tooltipback_rect.X < this.Items[i - 1].TipRect.Right + line_area))
                        {
                            tooltipback_rect.X = (int)this.Items[i - 1].TipRect.Right + line_area;
                        }
                    }
                    else if (this.Orientation == SlideOrientation.VerticalLeft)
                    {
                        tooltipback_rect.X = (int)this.Items[i].RectF.Right + this.BackdropThickness;
                        tooltipback_rect.Y = (int)this.Items[i].RectF.Y + ((int)this.Items[i].RectF.Height - tooltipback_rect.Height) / 2;
                        if (tooltipback_rect.Y > rectf.Bottom - tooltipback_rect.Height)
                            tooltipback_rect.Y = rectf.Bottom - tooltipback_rect.Height;
                        if (i > 0 && (tooltipback_rect.Y > (int)this.Items[i - 1].TipRect.Y - line_area - tooltipback_rect.Height))
                        {
                            tooltipback_rect.Y = (int)this.Items[i - 1].TipRect.Y - line_area - tooltipback_rect.Height;
                        }
                    }
                    else if (this.Orientation == SlideOrientation.VerticalRight)
                    {
                        tooltipback_rect.X = (int)this.Items[i].RectF.X - this.BackdropThickness - tooltipback_rect.Width;
                        tooltipback_rect.Y = (int)this.Items[i].RectF.Y + ((int)this.Items[i].RectF.Height - tooltipback_rect.Height) / 2;
                        if (tooltipback_rect.Y > rectf.Bottom - tooltipback_rect.Height)
                            tooltipback_rect.Y = rectf.Bottom - tooltipback_rect.Height;
                        if (i > 0 && (tooltipback_rect.Y > (int)this.Items[i - 1].TipRect.Y - line_area - tooltipback_rect.Height))
                        {
                            tooltipback_rect.Y = (int)this.Items[i - 1].TipRect.Y - line_area - tooltipback_rect.Height;
                        }
                    }

                    this.Items[i].TipRect = tooltipback_rect;
                }
                #endregion
            }

            #region
            if (this.TipShow != TipShowEnum.None)
            {
                for (int i = this.Items.Count - 1; i >= 0; i--)
                {
                    if (this.Orientation == SlideOrientation.HorizontalTop || this.Orientation == SlideOrientation.HorizontalBottom)
                    {
                        if ((i == this.Items.Count - 1))
                        {
                            if (this.Items[i].TipRect.Right > rectf.Right)
                                this.Items[i].TipRect = new Rectangle((int)(rectf.Right - this.Items[i].TipRect.Width), this.Items[i].TipRect.Y, this.Items[i].TipRect.Width, this.Items[i].TipRect.Height);
                        }
                        else
                        {
                            if (this.Items[i].TipRect.Right + line_area > this.Items[i + 1].TipRect.X)
                                this.Items[i].TipRect = new Rectangle((this.Items[i + 1].TipRect.X - this.Items[i].TipRect.Width - line_area), this.Items[i].TipRect.Y, this.Items[i].TipRect.Width, this.Items[i].TipRect.Height);
                        }

                        this.Items[i].Slidepoint = new PointF(this.Items[i].RectF.X + this.Items[i].RectF.Width / 2, this.Items[i].RectF.Bottom);
                        this.Items[i].Tippoint = new PointF(this.Items[i].TipRect.X + this.Items[i].TipRect.Width / 2, this.Items[i].TipRect.Y);
                        if (this.Orientation == SlideOrientation.HorizontalBottom)
                        {
                            this.Items[i].Slidepoint = new PointF(this.Items[i].RectF.X + this.Items[i].RectF.Width / 2, this.Items[i].RectF.Y);
                            this.Items[i].Tippoint = new PointF(this.Items[i].TipRect.X + this.Items[i].TipRect.Width / 2, this.Items[i].TipRect.Bottom);
                        }
                    }
                    else if (this.Orientation == SlideOrientation.VerticalLeft || this.Orientation == SlideOrientation.VerticalRight)
                    {
                        if (i == this.Items.Count - 1)
                        {
                            if (this.Items[i].TipRect.Y < rectf.Y)
                                this.Items[i].TipRect = new Rectangle(this.Items[i].TipRect.X, rectf.Y, this.Items[i].TipRect.Width, this.Items[i].TipRect.Height);
                        }
                        else
                        {
                            if (this.Items[i].TipRect.Y < this.Items[i + 1].TipRect.Bottom + line_area)
                                this.Items[i].TipRect = new Rectangle(this.Items[i].TipRect.X, this.Items[i + 1].TipRect.Bottom + line_area, this.Items[i].TipRect.Width, this.Items[i].TipRect.Height);
                        }

                        this.Items[i].Slidepoint = new PointF(this.Items[i].RectF.Right, this.Items[i].RectF.Bottom - this.Items[i].RectF.Height / 2);
                        this.Items[i].Tippoint = new PointF(this.Items[i].TipRect.Left, this.Items[i].TipRect.Bottom - this.Items[i].TipRect.Height / 2);
                        if (this.Orientation == SlideOrientation.VerticalRight)
                        {
                            this.Items[i].Slidepoint = new PointF(this.Items[i].RectF.X, this.Items[i].RectF.Bottom - this.Items[i].RectF.Height / 2);
                            this.Items[i].Tippoint = new PointF(this.Items[i].TipRect.Right, this.Items[i].TipRect.Bottom - this.Items[i].TipRect.Height / 2);
                        }
                    }

                    if (this.TipShow == TipShowEnum.Always || ((this.TipShow == TipShowEnum.Auto) && (this.SelectIndex == i) && (this.move_status == MoveStatus.Down) && (this.Items[i].Visuable)))
                    {
                        if (this.LineShow)
                            g.DrawLine(tooltipline_pen, this.Items[i].Slidepoint, this.Items[i].Tippoint);
                        g.FillRectangle(tooltipback_sb, this.Items[i].TipRect);
                        string tooltiptext_str = this.Items[i].Value.ToString("F2");
                        TextRenderer.DrawText(g, tooltiptext_str, this.TipFont, this.Items[i].TipRect, this.TipColor, TextFormatFlags.NoPadding | TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
                    }
                }
            }
            #endregion

            tooltipback_sb.Dispose();
            tooltipline_pen.Dispose();

            #endregion
        }
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);

            this.InitializeSlideValueRectangleFs();
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            this.move_status = MoveStatus.Down;
            if(!this.SlideFixed)
            {
                Point point = this.PointToClient(Control.MousePosition);
                this.move_point = point;
                this.selectIndex = this.GetSelectSlideIndex(point);
            }
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);

            if(this.SelectIndex > -1 && this.CanRemoveSlide)
            {
                Point point = this.PointToClient(Control.MousePosition);
                if (this.Orientation == SlideOrientation.HorizontalBottom || this.Orientation == SlideOrientation.HorizontalTop)
                {
                    if (Math.Abs(point.Y - this.Items[this.SelectIndex].RectF.Y) > 100)
                        this.Items.RemoveAt(this.SelectIndex);
                    else
                        this.Items[this.SelectIndex].Visuable = true;
                }
                if (this.Orientation == SlideOrientation.VerticalLeft || this.Orientation == SlideOrientation.VerticalRight)
                {
                    if (Math.Abs(point.X - this.Items[this.SelectIndex].RectF.X) > 100)
                        this.Items.RemoveAt(this.SelectIndex);
                    else
                        this.Items[this.SelectIndex].Visuable = true;
                }
            }
            this.move_status = MoveStatus.Up;
            this.selectIndex = -1;
            this.Invalidate();
        }
        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);

            this.move_status = MoveStatus.Enter;
        }
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);

            this.move_status = MoveStatus.Leave;
            this.selectIndex = -1;
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if(!this.SlideFixed)
            {
                Point point = this.PointToClient(Control.MousePosition);
                if (this.move_status == MoveStatus.Down)
                {
                    if (this.SelectIndex > -1 && !this.Items[this.SelectIndex].Fixed)
                    {
                        this.InitializeSlideValue(this.Items[this.SelectIndex]);
                        if (this.CanRemoveSlide)
                        {
                            if (this.Orientation == SlideOrientation.HorizontalBottom || this.Orientation == SlideOrientation.HorizontalTop)
                            {
                                if (Math.Abs(point.Y - this.Items[this.SelectIndex].RectF.Y) > 100)
                                    this.Items[this.SelectIndex].Visuable = false;
                                else
                                    this.Items[this.SelectIndex].Visuable = true;
                            }
                            if (this.Orientation == SlideOrientation.VerticalLeft || this.Orientation == SlideOrientation.VerticalRight)
                            {
                                if (Math.Abs(point.X - this.Items[this.SelectIndex].RectF.X) > 100)
                                    this.Items[this.SelectIndex].Visuable = false;
                                else
                                    this.Items[this.SelectIndex].Visuable = true;
                            }
                        }
                    }
                }
                else
                {
                    this.Cursor = (this.GetSelectSlideIndex(point) < 0 || this.Items[this.GetSelectSlideIndex(point)].Fixed) ? Cursors.Default : Cursors.Hand;
                }
            }
        }
        protected override void OnDoubleClick(EventArgs e)
        {
            base.OnDoubleClick(e);
            if (this.EnableColorChange && this.SelectIndex > -1)
            {
                int index = this.SelectIndex;
                ColorDialog edt = new ColorDialog();
                edt.Color = this.Items[index].SlideColor;
                edt.ShowDialog();
                this.Items[index].SlideColor = edt.Color;
            }
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
        #endregion

        #region 自定义方法

        /// <summary>
        /// 根据当前鼠标坐标计算滑块值
        /// </summary>
        /// <param name="item">当前滑块</param>
        private void InitializeSlideValue(SlideValue item)
        {
            Rectangle rect = new Rectangle(this.SlidePadding, this.SlidePadding, this.ClientRectangle.Width - this.SlidePadding * 2, this.ClientRectangle.Height - this.SlidePadding * 2);
            Point point = this.PointToClient(Control.MousePosition);

            if (this.Orientation == SlideOrientation.HorizontalTop || this.Orientation == SlideOrientation.HorizontalBottom)
            {
                if (point.X == this.move_point.X)
                    return;

                int index = this.Items.IndexOf(item);
                float value_l = this.maxValue - this.minValue;//值的总范围
                float back_l = rect.Width - this.CursorWidth - (this.Items.Count - 1) * this.CursorWidth - this.SlideSize;//背景总像素长度
                float increment = value_l / back_l;//一个像素代表的增量

                float value = item.Value;
                value += increment * (point.X - this.move_point.X);
                this.move_point = point;

                item.Value = value;
            }
            else
            {
                if (point.Y == this.move_point.Y)
                    return;

                int index = this.Items.IndexOf(item);
                float value_l = this.maxValue - this.minValue;//值的总范围
                float back_l = rect.Height - this.CursorWidth - (this.Items.Count - 1) * this.CursorWidth - this.SlideSize;//背景总长度
                float increment = value_l / back_l;//一个像素代表的增量

                float value = item.Value;
                value -= increment * (point.Y - this.move_point.Y);
                this.move_point = point;

                item.Value = value;
            }
        }

        /// <summary>
        /// 计算所有滑块rectf
        /// </summary>
        /// <param name="item"></param>
        private void InitializeSlideValueRectangleFs()
        {
            for (int i = 0; i < this.Items.Count; i++)
            {
                this.InitializeSlideValueRectangleF(this.Items[i]);
            }
        }

        /// <summary>
        /// 计算指定滑块rectf
        /// </summary>
        /// <param name="item"></param>
        private void InitializeSlideValueRectangleF(SlideValue item)
        {
            Rectangle rect = new Rectangle(this.SlidePadding, this.SlidePadding, this.ClientRectangle.Width - this.SlidePadding * 2, this.ClientRectangle.Height - this.SlidePadding * 2);

            int index = this.Items.IndexOf(item);
            if (this.Orientation == SlideOrientation.HorizontalBottom || this.Orientation == SlideOrientation.HorizontalTop)
            {
                float back_l = rect.Width - this.CursorWidth - (this.Items.Count - 1) * this.CursorWidth - this.SlideSize;
                int slide_x = this.SlidePadding + (this.SlideSize / 2) + (int)((item.Value - this.minValue) / (this.maxValue - this.minValue) * back_l);
                if (slide_x < 0)
                    slide_x = 0;
                if (slide_x > rect.Right - this.SlideSize / 2)
                    slide_x = rect.Right - this.SlideSize / 2;
                int slide_y = (this.Orientation == SlideOrientation.HorizontalTop) ? rect.Y : rect.Bottom - this.SlideSize * 2 - this.SlidePadding;
                item.RectF = new RectangleF(slide_x - (this.SlideSize / 2) + index * this.CursorWidth, slide_y, this.SlideSize, this.SlideSize * 2);
            }
            else
            {
                float back_l = rect.Height - this.CursorWidth - (this.Items.Count - 1) * this.CursorWidth - this.SlideSize;
                int slide_y = rect.Bottom - (this.SlideSize / 2) - (int)((item.Value - this.minValue) / (this.maxValue - this.minValue) * back_l);
                if (slide_y < 0)
                    slide_y = 0;
                if (slide_y > rect.Bottom - this.SlideSize / 2)
                    slide_y = rect.Bottom - this.SlideSize / 2;
                int slide_x = (this.Orientation == SlideOrientation.VerticalLeft) ? rect.X : rect.Right - this.SlideSize * 2 - this.SlidePadding;
                item.RectF = new RectangleF(slide_x, slide_y - (this.SlideSize / 2) - index * this.CursorWidth, this.SlideSize * 2, this.SlideSize);
            }
        }

        /// <summary>
        /// 获取选中滑块索引
        /// </summary>
        /// <param name="point">当前鼠标坐标</param>
        /// <returns></returns>
        private int GetSelectSlideIndex(Point point)
        {
            for (int i = 0; i < this.Items.Count; i++)
            {
                if (this.Items[i].RectF.Contains(point))
                    return i;
            }
            return -1;
        }

        /// <summary>
        /// 根据画笔大小转换rectf
        /// </summary>
        /// <param name="rectf">要转换的rectf</param>
        /// <param name="pen">画笔大小大小</param>
        /// <returns></returns>
        private static RectangleF TransformRectangleF(RectangleF rectf, int pen)
        {
            RectangleF result = new RectangleF();
            result.Width = rectf.Width - (pen < 1 ? 0 : pen);
            result.Height = rectf.Height - (pen < 1 ? 0 : pen);
            result.X = rectf.X + (float)(pen / 2);
            result.Y = rectf.Y + (float)(pen / 2);
            return result;
        }

        /// <summary>
        /// 转换成圆角
        /// </summary>
        /// <param name="rectf">要转换的rectf</param>
        /// <param name="radius">圆角半径的大小</param>
        /// <returns></returns>
        private static GraphicsPath TransformCircular(RectangleF rectf, int radius = 0)
        {
            return TransformCircular(rectf, radius, radius, radius, radius);
        }

        /// <summary>
        /// 转换成圆角
        /// </summary>
        /// <param name="rectf">要转换的rectf</param>
        /// <param name="leftTopRadius">左上角</param>
        /// <param name="rightTopRadius">右上角</param>
        /// <param name="rightBottomRadius">右下角</param>
        /// <param name="leftBottomRadius">左下角</param>
        /// <returns></returns>
        private static GraphicsPath TransformCircular(RectangleF rectf, int leftTopRadius = 0, int rightTopRadius = 0, int rightBottomRadius = 0, int leftBottomRadius = 0)
        {
            GraphicsPath gp = new GraphicsPath();
            if (leftTopRadius > 0)
            {
                RectangleF lefttop_rect = new RectangleF(rectf.X, rectf.Y, leftTopRadius * 2, leftTopRadius * 2);
                gp.AddArc(lefttop_rect, 180, 90);
            }
            else
            {
                gp.AddLine(new PointF(rectf.X, rectf.Y), new PointF(rightTopRadius > 0 ? rectf.Right - rightTopRadius * 2 : rectf.Right, rectf.Y));
            }
            if (rightTopRadius > 0)
            {
                RectangleF righttop_rect = new RectangleF(rectf.Right - rightTopRadius * 2, rectf.Y, rightTopRadius * 2, rightTopRadius * 2);
                gp.AddArc(righttop_rect, 270, 90);
            }
            else
            {
                gp.AddLine(new PointF(rectf.Right, rectf.Y), new PointF(rectf.Right, rightBottomRadius > 0 ? rectf.Bottom - rightTopRadius * 2 : rectf.Bottom));
            }
            if (rightBottomRadius > 0)
            {
                RectangleF rightbottom_rect = new RectangleF(rectf.Right - rightTopRadius * 2, rectf.Bottom - rightTopRadius * 2, rightBottomRadius * 2, rightBottomRadius * 2);
                gp.AddArc(rightbottom_rect, 0, 90);
            }
            else
            {
                gp.AddLine(new PointF(rectf.Right, rectf.Bottom), new PointF(leftBottomRadius > 0 ? leftBottomRadius * 2 : rectf.X, rectf.Bottom));
            }
            if (leftBottomRadius > 0)
            {
                RectangleF rightbottom_rect = new RectangleF(rectf.X, rectf.Bottom - leftBottomRadius * 2, leftBottomRadius * 2, leftBottomRadius * 2);
                gp.AddArc(rightbottom_rect, 90, 90);
            }
            else
            {
                gp.AddLine(new PointF(rectf.X, rectf.Bottom), new PointF(rectf.X, leftTopRadius > 0 ? rectf.X + leftTopRadius * 2 : rectf.X));
            }
            gp.CloseAllFigures();
            return gp;
        }

        #endregion

        /// <summary>
        /// 滑块选项集合
        /// </summary>
        [Description("滑块选项集合")]
        [Editor(typeof(CollectionEditorExt), typeof(UITypeEditor))]
        public sealed class SlideValueCollection : IList, ICollection, IEnumerable
        {
            private ArrayList slideValueList = new ArrayList();
            private SlideBarExt owner;

            public SlideValueCollection(SlideBarExt owner)
            {
                this.owner = owner;
            }

            #region IEnumerable

            public IEnumerator GetEnumerator()
            {
                SlideValue[] listArray = new SlideValue[this.slideValueList.Count];
                for (int index = 0; index < listArray.Length; ++index)
                    listArray[index] = (SlideValue)this.slideValueList[index];
                return listArray.GetEnumerator();
            }

            #endregion

            #region ICollection

            public void CopyTo(Array array, int index)
            {
                for (int i = 0; i < this.Count; i++)
                    array.SetValue(this.slideValueList[i], i + index);
            }

            public int Count
            {
                get
                {
                    return this.slideValueList.Count;
                }
            }

            public bool IsSynchronized
            {
                get
                {
                    return false;
                }
            }

            public object SyncRoot
            {
                get
                {
                    return (object)this;
                }
            }

            #endregion

            #region IList

            public int Add(object value)
            {
                SlideValue slideValue = (SlideValue)value;
                slideValue.owner = this.owner;
                slideValue.self = slideValue;
                this.slideValueList.Add(slideValue);
                this.owner.InitializeSlideValueRectangleF(slideValue);
                this.owner.Invalidate();
                return this.Count - 1;
            }

            public void Clear()
            {
                this.slideValueList.Clear();
                this.owner.Invalidate();
            }

            public bool Contains(object value)
            {
                return this.IndexOf(value) != -1;
            }

            public int IndexOf(object value)
            {
                return this.slideValueList.IndexOf(value);
            }

            public void Insert(int index, object value)
            {
                throw new NotImplementedException();
            }

            public bool IsFixedSize
            {
                get { return false; }
            }

            public bool IsReadOnly
            {
                get { return false; }
            }

            public void Remove(object value)
            {
                if (!(value is SlideValue))
                    return;
                this.slideValueList.Remove((SlideValue)value);
                this.owner.Invalidate();
            }

            public void RemoveAt(int index)
            {
                this.slideValueList.RemoveAt(index);
                this.owner.Invalidate();
            }

            public SlideValue this[int index]
            {
                get
                {
                    return (SlideValue)this.slideValueList[index];
                }
                set
                {
                    this.slideValueList[index] = (SlideValue)value;
                    this.owner.InitializeSlideValueRectangleF((SlideValue)value);
                    this.owner.Invalidate();
                }
            }

            object IList.this[int index]
            {
                get
                {
                    return (object)this.slideValueList[index];
                }
                set
                {
                    this.slideValueList[index] = (SlideValue)value;
                    this.owner.InitializeSlideValueRectangleF((SlideValue)value);
                    this.owner.Invalidate();
                }
            }

            #endregion

        }

        /// <summary>
        /// 滑块选项
        /// </summary>
        [Description("滑块选项")]
        public class SlideValue
        {
            public SlideValue()
            {

            }

            public SlideValue(SlideBarExt owner)
            {
                this.owner = owner;
            }

            /// <summary>
            /// 控件主体
            /// </summary>
            public SlideBarExt owner;
            /// <summary>
            /// 当前滑块选项
            /// </summary>
            public SlideValue self;

            private RectangleF rectf = new RectangleF();
            /// <summary>
            /// 滑块rectf
            /// </summary>
            [Browsable(false)]
            [Description("滑块rectf")]
            public RectangleF RectF
            {
                get { return this.rectf; }
                set
                {
                    if (this.rectf == value)
                        return;
                    this.rectf = value;
                }
            }

            private Rectangle tiprect = new Rectangle();
            /// <summary>
            /// 滑块提示信息rect
            /// </summary>
            [Browsable(false)]
            [Description("滑块提示信息rect")]
            public Rectangle TipRect
            {
                get { return this.tiprect; }
                set
                {
                    if (this.tiprect == value)
                        return;
                    this.tiprect = value;
                }
            }


            private PointF slidepoint = new Point();
            /// <summary>
            /// 连线滑块的坐标
            /// </summary>
            [Browsable(false)]
            [Description("连线滑块的坐标")]
            public PointF Slidepoint
            {
                get { return this.slidepoint; }
                set
                {
                    if (this.slidepoint == value)
                        return;
                    this.slidepoint = value;
                }
            }

            private PointF tippoint = new Point();
            /// <summary>
            /// 连线提示信息的坐标
            /// </summary>
            [Browsable(false)]
            [Description("连线提示信息的坐标")]
            public PointF Tippoint
            {
                get { return this.tippoint; }
                set
                {
                    if (this.tippoint == value)
                        return;
                    this.tippoint = value;
                }
            }


            private float value { get; set; }
            /// <summary>
            /// 滑块值
            /// </summary>
            [Browsable(true)]
            [DefaultValue("0f")]
            [Description("滑块值")]
            public float Value
            {
                get { return this.value; }
                set
                {
                    if (this.value == value)
                        return;

                    if (this.owner != null)
                    {
                        if (value < this.owner.MinValue)
                            value = this.owner.MinValue;
                        if (value > this.owner.MaxValue)
                            value = this.owner.MaxValue;

                        int index = this.owner.Items.IndexOf(self);
                        if (this.owner.Items.Count > 1)
                        {
                            if (value > this.value)//往右移动
                            {
                                if (index < this.owner.Items.Count - 1)
                                {
                                    if (value > this.owner.Items[index + 1].Value)
                                    {
                                        this.owner.Items[index + 1].Value = value;
                                    }
                                }
                            }
                            else if (value < this.value)
                            {
                                if (index > 0)
                                {
                                    if (value < this.owner.Items[index - 1].Value)
                                    {
                                        this.owner.Items[index - 1].Value = value;
                                    }
                                }
                            }
                        }

                        this.value = value;

                        this.owner.InitializeSlideValueRectangleF(self);
                        this.owner.Invalidate();

                        if (this.owner.slideValueChanged != null)
                        {
                            this.owner.slideValueChanged(this.owner, new SlideValueEventArgs() { Item = self });
                        }
                    }
                }
            }

            private Color slideColor = Color.Empty;
            /// <summary>
            /// 滑块颜色
            /// </summary>
            [Browsable(true)]
            [DefaultValue(typeof(Color), "Empty")]
            [Description("滑块颜色")]
            [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
            public Color SlideColor
            {
                get { return this.slideColor; }
                set
                {
                    if (this.slideColor == value)
                        return;
                    this.slideColor = value;
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                        if(this.owner.slideColorChanged != null)
                        {
                            this.owner.slideColorChanged(this.owner, new SlideValueEventArgs() { Item = self });
                        }
                    }
                }
            }

            private bool visuable = true;
            [Browsable(false)]
            [DefaultValue(true)]
            [Description("是否显示该滑块")]
            public bool Visuable
            {
                get { return this.visuable; }
                set
                {
                    if (this.visuable == value)
                        return;
                    this.visuable = value;
                }
            }

            private bool fix = false;
            [Browsable(true)]
            [DefaultValue(false)]
            [Description("滑块是否固定")]
            public bool Fixed
            {
                get { return this.fix; }
                set
                {
                    if (this.fix == value)
                        return;
                    this.fix = value;
                }
            }
        }

        /// <summary>
        /// 滑块选项值更改事件参数
        /// </summary>
        [Description("滑块选项值更改事件参数")]
        public class SlideValueEventArgs : EventArgs
        {
            /// <summary>
            /// 滑块选项
            /// </summary>
            [Description("滑块选项")]
            public SlideValue Item { get; set; }
        }

        /// <summary>
        /// 鼠标状态
        /// </summary>
        [Description("鼠标状态")]
        private enum MoveStatus
        {
            /// <summary>
            /// 鼠标进入
            /// </summary>
            Enter,
            /// <summary>
            /// 鼠标离开
            /// </summary>
            Leave,
            /// <summary>
            /// 鼠标按下
            /// </summary>
            Down,
            /// <summary>
            /// 鼠标按下释放
            /// </summary>
            Up
        }

        /// <summary>
        /// 控件滑块方向位置
        /// </summary>
        [Description("控件滑块方向位置")]
        public enum SlideOrientation
        {
            /// <summary>
            ///水平放置靠近上边
            /// </summary>
            HorizontalTop,
            /// <summary>
            /// 水平放置靠近下边
            /// </summary>
            HorizontalBottom,
            /// <summary>
            /// 垂直放置靠近左边
            /// </summary>
            VerticalLeft,
            /// <summary>
            /// 垂直放置靠近右边
            /// </summary>
            VerticalRight,
        }

        /// <summary>
        /// 滑块值标签显示方式
        /// </summary>
        [Description("滑块值标签显示方式")]
        public enum TipShowEnum
        {
            /// <summary>
            /// 不显示
            /// </summary>
            None,
            /// <summary>
            /// 一直显示
            /// </summary>
            Always,
            /// <summary>
            /// 点击时显示
            /// </summary>
            Auto,
        }
    }
}
